<template>
  <a-card :key="props.recode.id + props.colSpan" :title="props.recode.chartTitle" size="small">
    <template #extra>
      <a-space size="small">
        <a-select
          ref="select"
          v-model:value="selectedValue"
          style="width: 120px"
          :disabled="selectedDisabled"
          size="small"
          @change="refreshChart('dd', selectedValue)"
        >
          <a-select-option value="1">最近1个月</a-select-option>
          <a-select-option value="3">最近3个月</a-select-option>
          <a-select-option value="6">最近6个月</a-select-option>
          <a-select-option value="12">最近一年</a-select-option>
        </a-select>
        <a-space v-if="false" :size="0">
          <a-button size="small" @click="refreshChart('dd', selectedValue)">日</a-button>
          <a-button size="small" @click="refreshChart('MM')">月</a-button>
          <a-button size="small" @click="refreshChart('yyyy')">年</a-button>
        </a-space>
      </a-space>
    </template>
    <div ref="chart" style="width: 100%; height: 500px"></div>
  </a-card>
</template>

<script lang="ts" setup>
import * as echarts from 'echarts';
import type { Chart, ChartConfig, ChartSeries } from '@/api/bizDashboard/bizDashboard';
import * as bizDashboardApi from '@/api/bizDashboard/bizDashboard';
import type { EChartsType } from 'echarts/types/dist/echarts';
import { numberToLabel } from '@/utils/numberUtil';

const props = defineProps<{
  recode: Chart;
  colSpan: unknown;
}>();

defineEmits<{
  (e: 'fullScreen'): void;
  (e: 'copyRecode'): void;
  (e: 'showEditTable'): void;
  (e: 'deleteRecode'): void;
}>();

//日期范围选择框
let selectedValue = ref('1');
let selectedDisabled = ref(false);

let chartConfig: ChartConfig = JSON.parse(props.recode.chartConfig);
// 指定图表的配置项和数据
type EChartsOption = echarts.EChartsOption;
let option: EChartsOption = {
  legend: {
    type: 'scroll',
    right: '30%',
  },
  tooltip: {
    trigger: 'axis',
    axisPointer: {
      type: 'line',
    },
    formatter(params: any) {
      let label = '';
      let sum = 0;
      params.forEach((item: any, index: any) => {
        if (index === 0) {
          label += `${item.axisValueLabel}<br/>`;
        }
        sum += item.value.bizValue;
        label += `${item.marker} ${item.seriesName} : ${numberToLabel(item.value.bizValue)}<br/>`;
        if (chartConfig.sumSerialName && index === params.length - 1) {
          label += `${chartConfig.sumSerialName} : ${numberToLabel(sum)}`;
        }
      });
      return label;
    },
  },
  toolbox: {
    show: true,
    feature: {
      dataZoom: {
        title: {
          zoom: '选择区域',
          back: '回退区域',
        },
        yAxisIndex: 'none',
      },
      dataView: { title: '原始数据', readOnly: true },
      magicType: {
        title: { line: '切换为折线图', bar: '切换为柱状图' },
        type: ['line', 'bar'],
      },
      restore: { show: false },
      saveAsImage: { show: false },
    },
  },
  dataset: [],
  // 声明一个 X 轴，类目轴（category）。默认情况下，类目轴对应到 dataset 第一列。
  xAxis: { type: 'category' },
  // 声明一个 Y 轴，数值轴。
  yAxis: {},
  // 声明多个 bar 系列，默认情况下，每个系列会自动对应到 dataset 的每一列。
  series: [],
  graphic: {
    type: 'text',
    left: 'center',
    top: 'middle',
    silent: true, // 不响应事件
    invisible: true, // true不显示，false显示
    style: {
      fill: '#9d9d9d',
      fontWeight: 'bold',
      text: '暂无数据',
      fontFamily: 'Microsoft YaHei',
      fontSize: '25px',
    },
  },
};

//声明多个 bar 系列，默认情况下，每个系列会自动对应到 dataset 的每一列。
option.series = chartConfig.series.map((chartSeries: ChartSeries) => {
  return {
    datasetId: chartSeries.serialId,
    type: 'line',
    smooth: true,
    name: chartSeries.serialName,
    markPoint: {
      data: [
        { type: 'max', name: 'Max' },
        { type: 'min', name: 'Min' },
      ],
      label: {
        show: true,
        formatter(param: any) {
          return numberToLabel(param.data.value);
        },
      },
    },
  };
});

onMounted(() => {
  initChart();
  refreshChart();
});

onUpdated(() => {
  initChart();
  myChart.setOption({
    dataset: chartData,
    graphic: {
      invisible: chartData.length > 0, // true不显示，false显示
    },
  });
});

// 使用ref创建虚拟DOM引用，使用时用main.value
const chart = ref();
// 基于准备好的dom，初始化echarts实例
let myChart: EChartsType;

function initChart() {
  // 基于准备好的dom，初始化echarts实例
  myChart = echarts.init(chart.value, 'dark');
  // 自适应高度
  myChart.getDom().style.height = window.innerHeight - 128 + 'px';
  myChart.resize();
  // 使用刚指定的配置项和数据显示图表。
  myChart.setOption(option);
}

//保存chart的数据，走onUpdated的时候，直接用即可
let chartData: any[] = [];

function refreshChart(bizDateTag = 'dd', bizDateScope = '1') {
  //只有日视图的时候，能够选时间范围
  selectedDisabled.value = bizDateTag != 'dd';
  myChart.showLoading({
    text: '努力加载中',
  });
  let hasData = false;
  chartConfig.series.map((chartSeries: ChartSeries) => {
    let bizName = props.recode.id + '-' + chartSeries.serialId;
    if (chartConfig.chartType == bizDashboardApi.ChartTypeDiff) {
      bizName = chartSeries.chartId + '-' + chartSeries.serialId;
    }
    let params = {
      chartType: chartConfig.chartType,
      bizName: bizName,
      bizDateTag: bizDateTag,
      bizDateScope: bizDateScope,
    };
    bizDashboardApi.metric(params).then(jsonResult => {
      myChart.hideLoading();
      if (!jsonResult) {
        return;
      }
      let index = chartData.findIndex(item => {
        return item.id === chartSeries.serialId;
      });
      let item = {
        // 用 dimensions 指定了维度的顺序。直角坐标系中，如果 X 轴 type 为 category，
        // 默认把第一个维度映射到 X 轴上，后面维度映射到 Y 轴上。
        // 如果不指定 dimensions，也可以通过指定 series.encode
        id: chartSeries.serialId,
        dimensions: ['bizDate', 'bizValue', 'bizDateTags', 'bizName'],
        source: jsonResult.result,
      };
      if (index < 0) {
        //不存在，添加
        chartData.push(item);
      } else {
        //存在，替换
        chartData.splice(index, 1, item);
      }
      if (jsonResult.result.length > 0) {
        hasData = true;
      }
      myChart.setOption({
        dataset: chartData,
        graphic: {
          invisible: hasData, // true不显示，false显示
        },
      });
    });
  });
}
</script>

<style lang="less" scoped></style>
